#include <string>
#include <cstring>
#include <securec.h>
#include <node_api.h>
#include <map>
#include <mutex>
#include <uv.h>

#include "napi/native_node_api.h"

#include "commtraff.h"
#include "commtraff_napi.h"
#include "commtraff_hilog.h"


namespace {
#define NAPI_BUF_LENGTH (256)
#define GET_PARAMS(env, info, num)    \
    size_t argc = num;                \
    napi_value argv[num] = {nullptr}; \
    napi_value thisVar = nullptr;     \
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr))


    std::map<std::string, napi_ref > g_eventMap;
    std::mutex g_eventMapLock;
    napi_env g_env;

    struct CbData {
        void *data;
        int32_t nums;
        int32_t argc;
        int32_t reason;
        int32_t total;
        std::string eventType;
    };

    const int32_t NAPI_ARGS_ONE = 1;
    const int32_t NAPI_ARGS_TWO = 2;

    const std::string ERR_MESSAGE_INVALID_PARAMS = "Input parameter error.";

    bool CheckArgsVal(napi_env env, bool assertion, const std::string &param, const std::string &msg)
    {
        if (!(assertion)) {
            std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The value of " + param + ": " + msg;
            napi_throw_error(env, std::to_string(COMMTRAFF_INVALID_PARAM).c_str(), errMsg.c_str());
            return false;
        }
        return true;
    }

    bool CheckArgsCount(napi_env env, bool assertion, const std::string &message) {
        if (!(assertion)) {
            std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + message;
            napi_throw_error(env, std::to_string(COMMTRAFF_INVALID_PARAM).c_str(), errMsg.c_str());
            return false;
        }
        return true;
    }

    bool CheckArgsType(napi_env env, bool assertion, const std::string &paramName, const std::string &type)
    {
        if (!(assertion)) {
            std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The type of " + paramName +
                                 " must be " + type;
            napi_throw_error(env, std::to_string(COMMTRAFF_INVALID_PARAM).c_str(), errMsg.c_str());
            return false;
        }
        return true;
    }

    // 提取创建字符串属性的通用函数
    void SetStringProperty(napi_env env, napi_value obj, const char *propName, const char *value) {
        napi_value propValue;
        napi_create_string_utf8(env, value, NAPI_AUTO_LENGTH, &propValue);
        napi_set_named_property(env, obj, propName, propValue);
    }

    // 提取创建整数属性的通用函数，处理无符号类型
    void SetIntProperty(napi_env env, napi_value obj, const char *propName, uint64_t value) {
        napi_value propValue;
        napi_create_bigint_uint64(env, value, &propValue);
        napi_set_named_property(env, obj, propName, propValue);
    }

    // 提取创建整数属性的通用函数，处理有符号类型
    void SetInt32Property(napi_env env, napi_value obj, const char *propName, int32_t value) {
        napi_value propValue;
        napi_create_int32(env, value, &propValue);
        napi_set_named_property(env, obj, propName, propValue);
    }

    // 从 JavaScript 对象中解析字符串属性
    bool ParseStringProperty(napi_env env, napi_value obj, const char *propName, char *buffer, size_t bufferSize) {
        napi_value propValue;
        napi_status status = napi_get_named_property(env, obj, propName, &propValue);
        if (status != napi_ok) {
            LOGE("Failed to get %s property", propName);
            return false;
        }
        size_t propLen;
        status = napi_get_value_string_utf8(env, propValue, nullptr, 0, &propLen);
        if (status != napi_ok) {
            LOGE("Failed to get %s length", propName);
            return false;
        }
        if (propLen >= bufferSize) {
            LOGE("%s value too long", propName);
            return false;
        }
        status = napi_get_value_string_utf8(env, propValue, buffer, bufferSize, &propLen);
        if (status != napi_ok) {
            LOGE("Failed to get %s value", propName);
            return false;
        }
        buffer[propLen] = '\0';
        return true;
    }

    // 从 JavaScript 对象中解析 CommTraffQueryRule
    bool ParseCommTraffQueryRule(napi_env env, napi_value obj, CommTraffQueryRule &rule) {
        // 解析 traffType
        napi_value traffTypeValue;
        napi_status status = napi_get_named_property(env, obj, "traffType", &traffTypeValue);
        if (status != napi_ok) {
            LOGE("Failed to get traffType property");
            return false;
        }
        int32_t traffTypeInt;
        status = napi_get_value_int32(env, traffTypeValue, &traffTypeInt);
        if (status != napi_ok) {
            LOGE("Failed to get traffType value");
            return false;
        }
        rule.traffType = static_cast<TraffType>(traffTypeInt);
        LOGI("traffType %d", traffTypeInt);

        // 解析 startTime
        napi_value startTimeValue;
        status = napi_get_named_property(env, obj, "startTime", &startTimeValue);
        if (status != napi_ok) {
            LOGE("Failed to get startTime property");
            return false;
        }
        
        // 获取 Date 对象的 getTime() 方法并调用
        napi_value getTimeFunc;
        status = napi_get_named_property(env, startTimeValue, "getTime", &getTimeFunc);
        if (status != napi_ok) {
            LOGE("Failed to get startTime.getTime property");
            return false;
        }
        
        napi_value startTimeMsValue;
        status = napi_call_function(env, startTimeValue, getTimeFunc, 0, nullptr, &startTimeMsValue);
        if (status != napi_ok) {
            LOGE("Failed to call startTime.getTime()");
            return false;
        }
        
        // 获取时间戳值（毫秒）
        double startTimeMs;
        status = napi_get_value_double(env, startTimeMsValue, &startTimeMs);
        if (status != napi_ok) {
            LOGE("Failed to get startTime milliseconds value");
            return false;
        }
        // 转换为秒并存储
        rule.startTime = static_cast<time_t>(startTimeMs / 1000);

        // 解析 endTime
        napi_value endTimeValue;
        status = napi_get_named_property(env, obj, "endTime", &endTimeValue);
        if (status != napi_ok) {
            LOGE("Failed to get endTime property");
            return false;
        }
        
        // 获取 Date 对象的 getTime() 方法并调用
        napi_value endTimeGetTimeFunc;
        status = napi_get_named_property(env, endTimeValue, "getTime", &endTimeGetTimeFunc);
        if (status != napi_ok) {
            LOGE("Failed to get endTime.getTime property");
            return false;
        }
        
        napi_value endTimeMsValue;
        status = napi_call_function(env, endTimeValue, endTimeGetTimeFunc, 0, nullptr, &endTimeMsValue);
        if (status != napi_ok) {
            LOGE("Failed to call endTime.getTime()");
            return false;
        }
        
        // 获取时间戳值（毫秒）
        double endTimeMs;
        status = napi_get_value_double(env, endTimeMsValue, &endTimeMs);
        if (status != napi_ok) {
            LOGE("Failed to get endTime milliseconds value");
            return false;
        }
        // 转换为秒并存储
        rule.endTime = static_cast<time_t>(endTimeMs / 1000);

        return true;
    }

    // 从 JavaScript 对象中解析 LinkTraff
    bool ParseLinkTraff(napi_env env, napi_value obj, LinkTraff &linkTraff) {
        if (!ParseStringProperty(env, obj, "ifName", (char *) linkTraff.ifName, sizeof(linkTraff.ifName))) {
            return false;
        }

        napi_value value;
        napi_status status;

        // 解析 time
        status = napi_get_named_property(env, obj, "time", &value);
        if (status != napi_ok ||
            napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&linkTraff.time)) != napi_ok) {
            LOGE("Failed to get time property");
            return false;
        }

        // 解析 txBytes
        status = napi_get_named_property(env, obj, "txBytes", &value);
        if (status != napi_ok || napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&linkTraff.txBytes)) != napi_ok) {
            LOGE("Failed to get txBytes property");
            return false;
        }

        // 解析 txPackets
        status = napi_get_named_property(env, obj, "txPackets", &value);
        if (status != napi_ok || napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&linkTraff.txPackets)) != napi_ok) {
            LOGE("Failed to get txPackets property");
            return false;
        }

        // 解析 rxBytes
        status = napi_get_named_property(env, obj, "rxBytes", &value);
        if (status != napi_ok || napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&linkTraff.rxBytes)) != napi_ok) {
            LOGE("Failed to get rxBytes property");
            return false;
        }

        // 解析 rxPackets
        status = napi_get_named_property(env, obj, "rxPackets", &value);
        if (status != napi_ok || napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&linkTraff.rxPackets)) != napi_ok) {
            LOGE("Failed to get rxPackets property");
            return false;
        }

        // 解析 rxErrPackets
        status = napi_get_named_property(env, obj, "rxErrPackets", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&linkTraff.rxErrPackets)) != napi_ok) {
            LOGE("Failed to get rxErrPackets property");
            return false;
        }

        // 解析 txErrPackets
        status = napi_get_named_property(env, obj, "txErrPackets", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&linkTraff.txErrPackets)) != napi_ok) {
            LOGE("Failed to get txErrPackets property");
            return false;
        }

        // 解析 rxDropPackets
        status = napi_get_named_property(env, obj, "rxDropPackets", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&linkTraff.rxDropPackets)) != napi_ok) {
            LOGE("Failed to get rxDropPackets property");
            return false;
        }

        // 解析 txDropPackets
        status = napi_get_named_property(env, obj, "txDropPackets", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&linkTraff.txDropPackets)) != napi_ok) {
            LOGE("Failed to get txDropPackets property");
            return false;
        }

        return true;
    }

    // 从 JavaScript 对象中解析 TransportTraff
    bool ParseTransportTraff(napi_env env, napi_value obj, TransportTraff &transportTraff) {
        if (!ParseStringProperty(env, obj, "ifName", (char *) transportTraff.ifName, sizeof(transportTraff.ifName))) {
            return false;
        }
        if (!ParseStringProperty(env, obj, "local", transportTraff.local, sizeof(transportTraff.local))) {
            return false;
        }
        if (!ParseStringProperty(env, obj, "remote", transportTraff.remote, sizeof(transportTraff.remote))) {
            return false;
        }

        napi_value value;
        napi_status status;

        // 解析 pid
        status = napi_get_named_property(env, obj, "pid", &value);
        if (status != napi_ok ||
            napi_get_value_int32(env, value, reinterpret_cast<int32_t *>(&transportTraff.pid)) != napi_ok) {
            LOGE("Failed to get pid property");
            return false;
        }

        // 解析 time
        status = napi_get_named_property(env, obj, "time", &value);
        if (status != napi_ok ||
            napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&transportTraff.time)) != napi_ok) {
            LOGE("Failed to get time property");
            return false;
        }

        // 解析 sockId
        status = napi_get_named_property(env, obj, "sockId", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &transportTraff.sockId) != napi_ok) {
            LOGE("Failed to get sockId property");
            return false;
        }

        // 解析 protocol
        status = napi_get_named_property(env, obj, "protocol", &value);
        if (status != napi_ok || napi_get_value_int32(env, value,
                                                      reinterpret_cast<int32_t *>(&transportTraff.protocol)) !=
                                 napi_ok) {
            LOGE("Failed to get protocol property");
            return false;
        }

        // 解析 sendBytes
        status = napi_get_named_property(env, obj, "sendBytes", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&transportTraff.sendBytes)) != napi_ok) {
            LOGE("Failed to get sendBytes property");
            return false;
        }

        // 解析 sendPacks
        status = napi_get_named_property(env, obj, "sendPacks", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&transportTraff.sendPacks)) != napi_ok) {
            LOGE("Failed to get sendPacks property");
            return false;
        }

        // 解析 recvBytes
        status = napi_get_named_property(env, obj, "recvBytes", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&transportTraff.recvBytes)) != napi_ok) {
            LOGE("Failed to get recvBytes property");
            return false;
        }

        // 解析 recvPacks
        status = napi_get_named_property(env, obj, "recvPacks", &value);
        if (status != napi_ok || napi_get_value_int64(env, value,
                                                      reinterpret_cast<int64_t *>(&transportTraff.recvPacks)) != napi_ok) {
            LOGE("Failed to get recvPacks property");
            return false;
        }

        return true;
    }

    // 从 JavaScript 对象中解析 SessionTraff
    bool ParseSessionTraff(napi_env env, napi_value obj, SessionTraff &sessionTraff) {
        if (!ParseStringProperty(env, obj, "localSessionName", (char *) sessionTraff.localSessionName,
                                 sizeof(sessionTraff.localSessionName))) {
            return false;
        }
        if (!ParseStringProperty(env, obj, "peerSessionName", (char *) sessionTraff.peerSessionName,
                                 sizeof(sessionTraff.peerSessionName))) {
            return false;
        }
        if (!ParseStringProperty(env, obj, "peerUdidHash", (char *) sessionTraff.peerUdidHash,
                                 sizeof(sessionTraff.peerUdidHash))) {
            return false;
        }

        napi_value value;
        napi_status status;

        // 解析 pid
        status = napi_get_named_property(env, obj, "pid", &value);
        if (status != napi_ok ||
            napi_get_value_int32(env, value, reinterpret_cast<int32_t *>(&sessionTraff.pid)) != napi_ok) {
            LOGE("Failed to get pid property");
            return false;
        }

        // 解析 time
        status = napi_get_named_property(env, obj, "time", &value);
        if (status != napi_ok ||
            napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&sessionTraff.time)) != napi_ok) {
            LOGE("Failed to get time property");
            return false;
        }

        // 解析 handle
        status = napi_get_named_property(env, obj, "handle", &value);
        if (status != napi_ok || napi_get_value_int32(env, value, &sessionTraff.handle) != napi_ok) {
            LOGE("Failed to get handle property");
            return false;
        }

        // 解析 channelId
        status = napi_get_named_property(env, obj, "channelId", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &sessionTraff.channelId) != napi_ok) {
            LOGE("Failed to get channelId property");
            return false;
        }

        // 解析 connId
        status = napi_get_named_property(env, obj, "connId", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &sessionTraff.connId) != napi_ok) {
            LOGE("Failed to get connId property");
            return false;
        }

        // 解析 sessionId
        status = napi_get_named_property(env, obj, "sessionId", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &sessionTraff.sessionId) != napi_ok) {
            LOGE("Failed to get sessionId property");
            return false;
        }

        // 解析 sessionType
        status = napi_get_named_property(env, obj, "sessionType", &value);
        if (status != napi_ok ||
            napi_get_value_int32(env, value, reinterpret_cast<int32_t *>(&sessionTraff.sessionType)) != napi_ok) {
            LOGE("Failed to get sessionType property");
            return false;
        }

        // 解析 sendBytes
        status = napi_get_named_property(env, obj, "sendBytes", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &sessionTraff.sendBytes) != napi_ok) {
            LOGE("Failed to get sendBytes property");
            return false;
        }

        // 解析 recvBytes
        status = napi_get_named_property(env, obj, "recvBytes", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &sessionTraff.recvBytes) != napi_ok) {
            LOGE("Failed to get recvBytes property");
            return false;
        }

        return true;
    }

    // 从 JavaScript 对象中解析 RpcTraff
    bool ParseRpcTraff(napi_env env, napi_value obj, RpcTraff &rpcTraff) {
        napi_value value;
        napi_status status;

        // 解析 proxyHandle
        status = napi_get_named_property(env, obj, "proxyHandle", &value);
        if (status != napi_ok || napi_get_value_int32(env, value, &rpcTraff.proxyHandle) != napi_ok) {
            LOGE("Failed to get proxyHandle property");
            return false;
        }

        // 解析 stubHandle
        status = napi_get_named_property(env, obj, "stubHandle", &value);
        if (status != napi_ok || napi_get_value_int32(env, value, &rpcTraff.stubHandle) != napi_ok) {
            LOGE("Failed to get stubHandle property");
            return false;
        }

        // 解析 sendDataLen
        status = napi_get_named_property(env, obj, "sendDataLen", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &rpcTraff.sendDataLen) != napi_ok) {
            LOGE("Failed to get sendDataLen property");
            return false;
        }

        // 解析 recvDataLen
        status = napi_get_named_property(env, obj, "recvDataLen", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &rpcTraff.recvDataLen) != napi_ok) {
            LOGE("Failed to get recvDataLen property");
            return false;
        }

        // 解析 recvDataSeq
        status = napi_get_named_property(env, obj, "recvDataSeq", &value);
        if (status != napi_ok || napi_get_value_bigint_uint64(env, value, &rpcTraff.recvDataSeq, nullptr) != napi_ok) {
            LOGE("Failed to get recvDataSeq property");
            return false;
        }

        // 解析 sendDataSeq
        status = napi_get_named_property(env, obj, "sendDataSeq", &value);
        if (status != napi_ok || napi_get_value_bigint_uint64(env, value, &rpcTraff.sendDataSeq, nullptr) != napi_ok) {
            LOGE("Failed to get sendDataSeq property");
            return false;
        }

        // 解析 time
        status = napi_get_named_property(env, obj, "time", &value);
        if (status != napi_ok ||
            napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&rpcTraff.time)) != napi_ok) {
            LOGE("Failed to get time property");
            return false;
        }

        // 解析 localpid
        status = napi_get_named_property(env, obj, "localpid", &value);
        if (status != napi_ok || napi_get_value_int32(env, value, reinterpret_cast<int32_t *>(&rpcTraff.localpid)) != napi_ok) {
            LOGE("Failed to get localpid property");
            return false;
        }

        // 解析 localuid
        status = napi_get_named_property(env, obj, "localuid", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, reinterpret_cast<uint32_t *>(&rpcTraff.localuid)) != napi_ok) {
            LOGE("Failed to get localuid property");
            return false;
        }

        // 解析 peerpid
        status = napi_get_named_property(env, obj, "peerpid", &value);
        if (status != napi_ok || napi_get_value_int32(env, value, reinterpret_cast<int32_t *>(&rpcTraff.peerpid)) != napi_ok) {
            LOGE("Failed to get peerpid property");
            return false;
        }

        // 解析 peeruid
        status = napi_get_named_property(env, obj, "peeruid", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, reinterpret_cast<uint32_t *>(&rpcTraff.peeruid)) != napi_ok) {
            LOGE("Failed to get peeruid property");
            return false;
        }

        return true;
    }

    // 从 JavaScript 对象中解析 WPA 层流量数据
    bool ParseWpaTraff(napi_env env, napi_value obj, WpaTraff &wpaTraff) {
        // 解析 ifName
        if (!ParseStringProperty(env, obj, "ifName", (char*)wpaTraff.ifName, sizeof(wpaTraff.ifName))) {
            return false;
        }

        napi_value value;
        napi_status status;

        // 解析 signal
        status = napi_get_named_property(env, obj, "signal", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.signal) != napi_ok) {
            LOGE("Failed to get signal property");
            return false;
        }

        // 解析 noise
        status = napi_get_named_property(env, obj, "noise", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.noise) != napi_ok) {
            LOGE("Failed to get noise property");
            return false;
        }

        // 解析 snr
        status = napi_get_named_property(env, obj, "snr", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.snr) != napi_ok) {
            LOGE("Failed to get snr property");
            return false;
        }

        // 解析 txrate
        status = napi_get_named_property(env, obj, "txrate", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.txrate) != napi_ok) {
            LOGE("Failed to get txrate property");
            return false;
        }

        // 解析 rxrate
        status = napi_get_named_property(env, obj, "rxrate", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.rxrate) != napi_ok) {
            LOGE("Failed to get rxrate property");
            return false;
        }

        // 解析 realTxrate
        status = napi_get_named_property(env, obj, "realTxrate", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.realTxrate) != napi_ok) {
            LOGE("Failed to get realTxrate property");
            return false;
        }

        // 解析 realRxrate
        status = napi_get_named_property(env, obj, "realRxrate", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.realRxrate) != napi_ok) {
            LOGE("Failed to get realRxrate property");
            return false;
        }

        // 解析 txEfficiency
        status = napi_get_named_property(env, obj, "txEfficiency", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.txEfficiency) != napi_ok) {
            LOGE("Failed to get txEfficiency property");
            return false;
        }

        // 解析 frequency
        status = napi_get_named_property(env, obj, "frequency", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.frequency) != napi_ok) {
            LOGE("Failed to get frequency property");
            return false;
        }

        // 解析 txPackets
        status = napi_get_named_property(env, obj, "txPackets", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.txPackets) != napi_ok) {
            LOGE("Failed to get txPackets property");
            return false;
        }

        // 解析 rxPackets
        status = napi_get_named_property(env, obj, "rxPackets", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.rxPackets) != napi_ok) {
            LOGE("Failed to get rxPackets property");
            return false;
        }

        // 解析 chload
        status = napi_get_named_property(env, obj, "chload", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, &wpaTraff.chload) != napi_ok) {
            LOGE("Failed to get chload property");
            return false;
        }

        // 解析 txBytes
        status = napi_get_named_property(env, obj, "txBytes", &value);
        if (status != napi_ok || napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&wpaTraff.txBytes)) != napi_ok) {
            LOGE("Failed to get txBytes property");
            return false;
        }

        // 解析 rxBytes
        status = napi_get_named_property(env, obj, "rxBytes", &value);
        if (status != napi_ok || napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&wpaTraff.rxBytes)) != napi_ok) {
            LOGE("Failed to get rxBytes property");
            return false;
        }

        // 解析 txFailed
        status = napi_get_named_property(env, obj, "txFailed", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.txFailed) != napi_ok) {
            LOGE("Failed to get txFailed property");
            return false;
        }

        // 解析 txRetries
        status = napi_get_named_property(env, obj, "txRetries", &value);
        if (status != napi_ok || napi_get_value_uint32(env, value, (uint32_t *)&wpaTraff.txRetries) != napi_ok) {
            LOGE("Failed to get txRetries property");
            return false;
        }

        // 解析 time
        status = napi_get_named_property(env, obj, "time", &value);
        if (status != napi_ok ||
            napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&wpaTraff.time)) != napi_ok) {
            LOGE("Failed to get time property");
            return false;
        }

        return true;
    }

    // 从 JavaScript 对象中解析 HisyseventData
    bool ParseHisyseventData(napi_env env, napi_value obj, HisyseventData &hisyseventData) {
        if (!ParseStringProperty(env, obj, "domain", hisyseventData.domain, sizeof(hisyseventData.domain))) {
            return false;
        }
        if (!ParseStringProperty(env, obj, "event", hisyseventData.event, sizeof(hisyseventData.event))) {
            return false;
        }
        if (!ParseStringProperty(env, obj, "field", hisyseventData.field, sizeof(hisyseventData.field))) {
            return false;
        }

        napi_value value;
        napi_status status;

        // 解析 value
        status = napi_get_named_property(env, obj, "value", &value);
        if (status != napi_ok || napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&hisyseventData.value)) != napi_ok) {
            LOGE("Failed to get value property");
            return false;
        }

        // 解析 time
        status = napi_get_named_property(env, obj, "time", &value);
        if (status != napi_ok ||
            napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&hisyseventData.time)) != napi_ok) {
            LOGE("Failed to get time property");
            return false;
        }

        return true;
    }

    // 从 JavaScript 对象中解析 CommTraff
    bool ParseCommTraff(napi_env env, napi_value obj, CommTraff &commTraff) {
        // 解析 traffType
        napi_value traffTypeValue;
        napi_status status = napi_get_named_property(env, obj, "traffType", &traffTypeValue);
        if (status != napi_ok) {
            LOGE("Failed to get traffType property");
            return false;
        }
        int32_t traffTypeInt;
        status = napi_get_value_int32(env, traffTypeValue, &traffTypeInt);
        if (status != napi_ok) {
            LOGE("Failed to get traffType value");
            return false;
        }
        commTraff.traffType = static_cast<TraffType>(traffTypeInt);

        // 解析 data
        napi_value dataValue;
        status = napi_get_named_property(env, obj, "data", &dataValue);
        if (status != napi_ok) {
            LOGE("Failed to get data property");
            return false;
        }

        switch (commTraff.traffType) {
            case TraffType::LINK_LAYER_DATA: {
                napi_value linkTraffValue;
                status = napi_get_named_property(env, dataValue, "linkTraff", &linkTraffValue);
                if (status != napi_ok) {
                    LOGE("Failed to get linkTraff property");
                    return false;
                }
                if (!ParseLinkTraff(env, linkTraffValue, commTraff.data.linkTraff))  {
                    return false;
                }
                break;
            }
            case TraffType::TRANSPORT_LAYER_DATA: {
                napi_value transportTraffValue;
                status = napi_get_named_property(env, dataValue, "transportTraff", &transportTraffValue);
                if (status != napi_ok) {
                    LOGE("Failed to get transportTraff property");
                    return false;
                }
                if (!ParseTransportTraff(env, transportTraffValue, commTraff.data.transportTraff)) {
                    return false;
                }
                break;
            }
            case TraffType::SESSION_LAYER_DATA: {
                napi_value sessionTraffValue;
                status = napi_get_named_property(env, dataValue, "sessionTraff", &sessionTraffValue);
                if (status != napi_ok) {
                    LOGE("Failed to get sessionTraff property");
                    return false;
                }
                if (!ParseSessionTraff(env, sessionTraffValue, commTraff.data.sessionTraff)) {
                    return false;
                }
                break;
            }
            case TraffType::RPC_LAYER_DATA: {
                napi_value rpcTraffValue;
                status = napi_get_named_property(env, dataValue, "rpcTraff", &rpcTraffValue);
                if (status != napi_ok) {
                    LOGE("Failed to get rpcTraff property");
                    return false;
                }
                if (!ParseRpcTraff(env, rpcTraffValue, commTraff.data.rpcTraff)) {
                    return false;
                }
                break;
            }
            case TraffType::WPA_LAYER_DATA: {
                napi_value wpaTraffValue;
                status = napi_get_named_property(env, dataValue, "wpaTraff", &wpaTraffValue);
                if (status != napi_ok) {
                    LOGE("Failed to get wpaTraff property");
                    return false;
                }
                if (!ParseWpaTraff(env, wpaTraffValue, commTraff.data.wpaTraff)) {
                    return false;
                }
                break;
            }
            case TraffType::HISYSEVENT_DATA: {
                napi_value hisyseventDataValue;
                status = napi_get_named_property(env, dataValue, "hisyseventData", &hisyseventDataValue);
                if (status != napi_ok) {
                    LOGE("Failed to get hisyseventData property");
                    return false;
                }
                if (!ParseHisyseventData(env, hisyseventDataValue, commTraff.data.hisyseventData)) {
                    return false;
                }
                break;
            }
            default:
                LOGE("Unsupported TraffType");
                return false;
        }

        return true;
    }

    // 封装链路层流量数据
    void PackLinkTraff(napi_env env, LinkTraff *linkTraff, napi_value dataObj) {
        napi_value linkTraffObj;
        napi_create_object(env, &linkTraffObj);

        SetStringProperty(env, linkTraffObj, "ifName", (const char *) linkTraff->ifName);
        SetIntProperty(env, linkTraffObj, "time", linkTraff->time);
        SetIntProperty(env, linkTraffObj, "txBytes", linkTraff->txBytes);
        SetIntProperty(env, linkTraffObj, "txPackets", linkTraff->txPackets);
        SetIntProperty(env, linkTraffObj, "rxBytes", linkTraff->rxBytes);
        SetIntProperty(env, linkTraffObj, "rxPackets", linkTraff->rxPackets);
        SetIntProperty(env, linkTraffObj, "rxErrPackets", linkTraff->rxErrPackets);
        SetIntProperty(env, linkTraffObj, "txErrPackets", linkTraff->txErrPackets);
        SetIntProperty(env, linkTraffObj, "rxDropPackets", linkTraff->rxDropPackets);
        SetIntProperty(env, linkTraffObj, "txDropPackets", linkTraff->txDropPackets);

        napi_set_named_property(env, dataObj, "linkTraff", linkTraffObj);
    }

    // 封装传输层流量数据
    void PackTransportTraff(napi_env env, TransportTraff *transportTraff, napi_value dataObj) {
        napi_value transportTraffObj;
        napi_create_object(env, &transportTraffObj);

        SetStringProperty(env, transportTraffObj, "ifName", (const char *) transportTraff->ifName);
        SetStringProperty(env, transportTraffObj, "local", (const char *) transportTraff->local);
        SetStringProperty(env, transportTraffObj, "remote", (const char *) transportTraff->remote);

        SetInt32Property(env, transportTraffObj, "pid", transportTraff->pid);
        SetIntProperty(env, transportTraffObj, "time", transportTraff->time);
        SetInt32Property(env, transportTraffObj, "sockId", transportTraff->sockId);
        SetInt32Property(env, transportTraffObj, "protocol", transportTraff->protocol);
        SetIntProperty(env, transportTraffObj, "sendBytes", transportTraff->sendBytes);
        SetIntProperty(env, transportTraffObj, "sendPacks", transportTraff->sendPacks);
        SetIntProperty(env, transportTraffObj, "recvBytes", transportTraff->recvBytes);
        SetIntProperty(env, transportTraffObj, "recvPacks", transportTraff->recvPacks);

        napi_set_named_property(env, dataObj, "transportTraff", transportTraffObj);
    }

    // 封装会话层流量数据
    void PackSessionTraff(napi_env env, SessionTraff *sessionTraff, napi_value dataObj) {
        napi_value sessionTraffObj;
        napi_create_object(env, &sessionTraffObj);

        SetStringProperty(env, sessionTraffObj, "localSessionName",
                          (const char *) sessionTraff->localSessionName);
        SetStringProperty(env, sessionTraffObj, "peerSessionName",
                          (const char *) sessionTraff->peerSessionName);
        SetStringProperty(env, sessionTraffObj, "peerUdidHash", (const char *) sessionTraff->peerUdidHash);

        SetInt32Property(env, sessionTraffObj, "pid", sessionTraff->pid);
        SetIntProperty(env, sessionTraffObj, "time", sessionTraff->time);
        SetInt32Property(env, sessionTraffObj, "handle", sessionTraff->handle);
        SetInt32Property(env, sessionTraffObj, "channelId", sessionTraff->channelId);
        SetInt32Property(env, sessionTraffObj, "connId", sessionTraff->connId);
        SetInt32Property(env, sessionTraffObj, "sessionId", sessionTraff->sessionId);
        SetInt32Property(env, sessionTraffObj, "sessionType", static_cast<int32_t>(sessionTraff->sessionType));
        SetIntProperty(env, sessionTraffObj, "sendBytes", sessionTraff->sendBytes);
        SetIntProperty(env, sessionTraffObj, "recvBytes", sessionTraff->recvBytes);

        napi_set_named_property(env, dataObj, "sessionTraff", sessionTraffObj);
    }

    // 封装RPC层流量数据
    void PackRpcTraff(napi_env env, RpcTraff *rpcTraff, napi_value dataObj) {
        napi_value rpcTraffObj;
        napi_create_object(env, &rpcTraffObj);

        SetInt32Property(env, rpcTraffObj, "proxyHandle", rpcTraff->proxyHandle);
        SetInt32Property(env, rpcTraffObj, "stubHandle", rpcTraff->stubHandle);
        SetInt32Property(env, rpcTraffObj, "sendDataLen", rpcTraff->sendDataLen);
        SetInt32Property(env, rpcTraffObj, "recvDataLen", rpcTraff->recvDataLen);
        SetIntProperty(env, rpcTraffObj, "recvDataSeq", rpcTraff->recvDataSeq);
        SetIntProperty(env, rpcTraffObj, "sendDataSeq", rpcTraff->sendDataSeq);
        SetIntProperty(env, rpcTraffObj, "time", rpcTraff->time);
        SetInt32Property(env, rpcTraffObj, "localpid", rpcTraff->localpid);
        SetInt32Property(env, rpcTraffObj, "localuid", rpcTraff->localuid);
        SetInt32Property(env, rpcTraffObj, "peerpid", rpcTraff->peerpid);
        SetInt32Property(env, rpcTraffObj, "peeruid", rpcTraff->peeruid);
        napi_set_named_property(env, dataObj, "rpcTraff", rpcTraffObj);
    }

    // 封装WPA层流量数据
    void PackWpaTraff(napi_env env, WpaTraff *wpaTraff, napi_value dataObj) {
        napi_value wpaTraffObj;
        napi_create_object(env, &wpaTraffObj);

        SetStringProperty(env, wpaTraffObj, "ifName", (const char *) wpaTraff->ifName);
        SetInt32Property(env, wpaTraffObj, "signal", wpaTraff->signal);
        SetInt32Property(env, wpaTraffObj, "noise", wpaTraff->noise);
        SetInt32Property(env, wpaTraffObj, "snr", wpaTraff->snr);
        SetInt32Property(env, wpaTraffObj, "txrate", wpaTraff->txrate);
        SetInt32Property(env, wpaTraffObj, "rxrate", wpaTraff->rxrate);
        SetInt32Property(env, wpaTraffObj, "realTxrate", wpaTraff->realTxrate);
        SetInt32Property(env, wpaTraffObj, "realRxrate", wpaTraff->realRxrate);
        SetInt32Property(env, wpaTraffObj, "txEfficiency", wpaTraff->txEfficiency);
        SetInt32Property(env, wpaTraffObj, "frequency", wpaTraff->frequency);
        SetInt32Property(env, wpaTraffObj, "txPackets", wpaTraff->txPackets);
        SetInt32Property(env, wpaTraffObj, "rxPackets", wpaTraff->rxPackets);
        SetInt32Property(env, wpaTraffObj, "chload", wpaTraff->chload);
        SetIntProperty(env, wpaTraffObj, "txBytes", wpaTraff->txBytes);
        SetIntProperty(env, wpaTraffObj, "rxBytes", wpaTraff->rxBytes);
        SetInt32Property(env, wpaTraffObj, "txFailed", wpaTraff->txFailed);
        SetInt32Property(env, wpaTraffObj, "txRetries", wpaTraff->txRetries);
        SetIntProperty(env, wpaTraffObj, "time", wpaTraff->time);

        napi_set_named_property(env, dataObj, "wpaTraff", wpaTraffObj);
    }

    // 封装WPA层流量数据
    void PackHiSysEventData(napi_env env, HisyseventData *evnet, napi_value dataObj)
    {
        napi_value hisyseventDataObj;
        napi_create_object(env, &hisyseventDataObj);

        SetStringProperty(env, hisyseventDataObj, "domain", evnet->domain);
        SetStringProperty(env, hisyseventDataObj, "event", evnet->event);
        SetStringProperty(env, hisyseventDataObj, "field", evnet->field);
        SetIntProperty(env, hisyseventDataObj, "value", evnet->value);
        SetIntProperty(env, hisyseventDataObj, "time", evnet->time);

        napi_set_named_property(env, dataObj, "hisyseventData", hisyseventDataObj);
    }

    napi_value PackTraffResult(CommTraff *records, int32_t nums)
    {
        // 创建 JavaScript 数组来存储记录
        napi_value recordsArray;
        napi_create_array(g_env, &recordsArray);

        // 遍历所有 CommTraff 记录
        for (int i = 0; i < nums; i++) {
            napi_value recordObj;
            napi_create_object(g_env, &recordObj);

            // 设置 traffType
            napi_value traffTypeValue;
            napi_create_int32(g_env, static_cast<int32_t>(records[i].traffType), &traffTypeValue);
            napi_set_named_property(g_env, recordObj, "traffType", traffTypeValue);

            // 设置 data
            napi_value dataObj;
            napi_create_object(g_env, &dataObj);

            switch (records[i].traffType) {
                case TraffType::LINK_LAYER_DATA:
                    PackLinkTraff(g_env, &records[i].data.linkTraff, dataObj);
                    break;
                case TraffType::TRANSPORT_LAYER_DATA:
                    PackTransportTraff(g_env, &records[i].data.transportTraff, dataObj);
                    break;
                case TraffType::SESSION_LAYER_DATA:
                    PackSessionTraff(g_env, &records[i].data.sessionTraff, dataObj);
                    break;
                case TraffType::RPC_LAYER_DATA:
                    PackRpcTraff(g_env, &records[i].data.rpcTraff, dataObj);
                    break;
                case TraffType::WPA_LAYER_DATA:
                    PackWpaTraff(g_env, &records[i].data.wpaTraff, dataObj);
                    break;
                case TraffType::HISYSEVENT_DATA:
                    PackHiSysEventData(g_env, &records[i].data.hisyseventData, dataObj);
                    break;
                default:
                    LOGE("Unsupported TraffType");
                    break;
            }

            napi_set_named_property(g_env, recordObj, "data", dataObj);

            // 将记录添加到数组
            napi_status status = napi_set_element(g_env, recordsArray, i, recordObj);
            if (status != napi_ok) {
                LOGE("OnQueryJSCallback To JsArray set element error: %d", status);
            }
        }

        // 创建包含 records 字段的对象
        napi_value resultObj;
        napi_create_object(g_env, &resultObj);
        napi_set_named_property(g_env, resultObj, "records", recordsArray);
        return resultObj;
    }

    napi_value PackageData(CbData* callback)
    {
        napi_value result = nullptr;
        // 如果是 OnTraffQuery 事件，调用 PackTraffResult
        if (strcmp(callback->eventType.c_str(), "OnTraffQuery") == 0) {
            result = PackTraffResult((CommTraff *)callback->data, callback->nums);
        // 如果是 OnComplete 事件，创建一个包含 reason 和 total 的对象
        } else if (strcmp(callback->eventType.c_str(), "OnComplete") == 0) {
            napi_create_object(g_env, &result);
            napi_value reasonValue;
            napi_create_int32(g_env, callback->reason, &reasonValue);
            napi_set_named_property(g_env, result, "reason", reasonValue);
            napi_value totalValue;
            napi_create_int32(g_env, callback->total, &totalValue);
            napi_set_named_property(g_env, result, "total", totalValue);
        }  else {
            LOGE("Unsupported event type: %s", callback->eventType.c_str());
        }
        return result;
    }

    int32_t EventNotify(CbData* callback)
    {
        LOGI("using EventNotify in %s",callback->eventType.c_str());
        uv_loop_s *loop = nullptr;
        napi_get_uv_event_loop(g_env, &loop);
        if (loop == nullptr) {
            LOGE("EventNotify, get uv loop failed");
            return COMMTRAFF_NULL_PTR;
        }
        //start async work
        uv_work_t *work = new (std::nothrow) uv_work_t;
        if (work == nullptr) {
            LOGE("EventNotify, No memory");
            return COMMTRAFF_MEM_ALLOC_FAIL;
        }
        work->data = reinterpret_cast<void *>(callback);

        int ret = uv_queue_work(loop, work, [] (uv_work_t *work) {},
                        [] (uv_work_t *work, int status) {
                            //新创建一个作用域
                            napi_handle_scope scope = nullptr;
                            napi_open_handle_scope(g_env, &scope);
                            CbData *callback = reinterpret_cast<CbData *>(work->data);
                            if (callback == nullptr) {
                                LOGE("EventNotify, callback is null");
                                napi_close_handle_scope(g_env, scope);
                                delete work;
                                return;
                            }
                            do {
                                napi_value result = nullptr;
                                //get NAPI/js return value
                                result = PackageData(callback);
                                if (result == nullptr) {
                                    LOGE("PackageData failed");
                                    break;
                                }
                                // to do napi listen callback
                                std::lock_guard<std::mutex> autoLock(g_eventMapLock);
                                auto iter = g_eventMap.find(callback->eventType);
                                if (iter == g_eventMap.end()) {
                                    LOGE("eventType %s not find", callback->eventType.c_str());
                                    break;
                                }

                                napi_value handler = nullptr;
                                napi_status res = napi_get_reference_value(g_env, iter->second, &handler);
                                if (res != napi_ok) {
                                    LOGE("napi_get_reference_value handler for %s failed, status = %d", callback->eventType.c_str(), status);
                                    break;
                                }

                                napi_value callResult = nullptr;
                                if (napi_call_function(g_env, nullptr, handler, callback->argc, &result, &callResult) != napi_ok) {
                                    LOGE("napi_call_function for %s failed, status = %d", callback->eventType.c_str(), status);
                                    break;
                                }
                            } while (false);
                            // 清理工作
                            if (callback->data != NULL) {
                                free(callback->data);
                                callback->data = NULL;
                            }
                            napi_close_handle_scope(g_env, scope);
                            delete callback;
                            delete work;
                        });
        if (ret != 0) {
            LOGE("Failed to execute uv_queue_work, ret=%d", ret);
            delete work;      // 清理work对象
            return COMMTRAFF_UV_WORK_FAIL;
        }
        return COMMTRAFF_SUCCESS;
    }

    void OnTraffQueryWrapper(CommTraff *records, int32_t nums)
    {
        LOGI("nums=%d", nums);
        CbData *callback = new (std::nothrow) CbData;
        if (callback == nullptr) {
            LOGE("OnTraffCompleteWrapper, No memory");
            return;
        }
        memset(callback, 0, sizeof(CbData));
        CommTraff *data = (CommTraff *) malloc(nums * sizeof(CommTraff));
        if (data == nullptr) {
            LOGE("OnTraffCompleteWrapper, No memory for data");
            delete callback;
            return;
        }
        memcpy(data, records, nums * sizeof(CommTraff));
        callback->data = data; // 将数据指针赋值给 callback
        callback->nums = nums;
        callback->eventType = "OnTraffQuery";
        callback->argc = NAPI_ARGS_ONE; // 设置参数个数
        if (EventNotify(callback) != COMMTRAFF_SUCCESS) {
            LOGE("OnTraffQueryWrapper, EventNotify failed");
            free(data);      // 释放数据内存
            delete callback; // 释放callback内存
            return;
        }
    }

    void OnTraffCompleteWrapper(int32_t reason, int32_t total)
    {
        LOGI("reason=%d total=%d", reason, total);
        CbData *callback = new (std::nothrow) CbData;
        if (callback == nullptr) {
            LOGE("OnTraffCompleteWrapper, No memory");
            return;
        }
        memset(callback, 0, sizeof(CbData));
        callback->eventType = "OnComplete";
        callback->reason = reason;
        callback->total = total;
        callback->argc = NAPI_ARGS_ONE; // 设置参数个数
        if (EventNotify(callback) != COMMTRAFF_SUCCESS) {
            LOGE("OnTraffCompleteWrapper, EventNotify failed");
            delete callback;
            return;
        }
    }

}
namespace OHOS {
namespace KhCommtraff {

    napi_value CommtraffInitJs(napi_env env, napi_callback_info info)
    {
        int32_t result = ::CommtraffInit();
        napi_value napiResult;
        napi_create_int32(env, result, &napiResult);
        LOGI("result = %d", result);
        g_env = env;
        return napiResult;
    }

    napi_value CommtraffDeinitJs(napi_env env, napi_callback_info info)
    {
        int32_t result = ::CommtraffDeinit();
        napi_value napiResult;
        napi_create_int32(env, result, &napiResult);
        LOGI("result = %d", result);
        return napiResult;
    }

    napi_value InsertCommTraffJs(napi_env env, napi_callback_info info)
    {
        GET_PARAMS(env, info, NAPI_ARGS_ONE);
        if (!CheckArgsCount(env, argc == NAPI_ARGS_ONE, "Wrong number of arguments, one argument needed")) {
            LOGE("InsertCommTraffJs argc != NAPI_ARGS_ONE");
            return nullptr;
        }

        CommTraff record;
        if (!ParseCommTraff(env, argv[0], record)) {
            napi_throw_error(env, std::to_string(COMMTRAFF_INVALID_PARAM).c_str(), "Failed to parse CommTraff record");
            LOGE("InsertCommTraffJs ParseCommTraff fail");
            return nullptr;
        }

        int32_t result = ::InsertCommTraff(&record);
        napi_value napiResult;
        napi_create_int32(env, result, &napiResult);
        LOGI("InsertCommTraff result = %d", result);
        return napiResult;
    }

    napi_value QueryCommTraffJs(napi_env env, napi_callback_info info)
    {
        LOGI("call");
        GET_PARAMS(env, info, NAPI_ARGS_ONE);
        if (!CheckArgsCount(env, argc == NAPI_ARGS_ONE, "Wrong number of arguments, two arguments needed")) {
            LOGE("QueryCommTraffJs argc != NAPI_ARGS_TWO");
            return nullptr;
        }

        // 解析查询规则
        CommTraffQueryRule queryRule;
        if (!ParseCommTraffQueryRule(env, argv[0], queryRule)) {
            napi_throw_error(env, std::to_string(COMMTRAFF_INVALID_PARAM).c_str(), "Failed to parse query rule");
            LOGE("QueryCommTraffJs ParseCommTraffQueryRule fail");
            return nullptr;
        }

        CommTraffQueryCb cb = {
                .OnQuery = OnTraffQueryWrapper,
                .OnComplete = OnTraffCompleteWrapper,
        };
        int32_t result = ::QueryCommTraff(&queryRule, &cb);
        napi_value napiResult;
        napi_create_int32(env, result, &napiResult);
        LOGI("result = %d", result);
        return napiResult;
    }

    napi_value QueryCommTraffNumsJs(napi_env env, napi_callback_info info)
    {
        GET_PARAMS(env, info, NAPI_ARGS_ONE);
        if (!CheckArgsCount(env, argc == NAPI_ARGS_ONE, "Wrong number of arguments, one argument needed")) {
            return nullptr;
        }

        CommTraffQueryRule queryRule;
        if (!ParseCommTraffQueryRule(env, argv[0], queryRule)) {
            napi_throw_error(env, std::to_string(COMMTRAFF_INVALID_PARAM).c_str(), "Failed to parse query rule");
            return nullptr;
        }

        int32_t result = ::QueryCommTraffNums(&queryRule);
        napi_value napiResult;
        napi_create_int32(env, result, &napiResult);
        LOGI("QueryCommTraffNums result = %d", result);
        return napiResult;
    }

    napi_value JsOn(napi_env env, napi_callback_info info)
    {
        LOGI("JsOn in");
        GET_PARAMS(env, info, NAPI_ARGS_TWO);
        if(thisVar == nullptr){
            LOGE("thisVar is nullptr");
        }
        napi_value result = nullptr;

        if (!CheckArgsCount(env, argc == NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
            return nullptr;
        }

        napi_valuetype eventValueType = napi_undefined;
        napi_typeof(env, argv[0], &eventValueType);
        if (!CheckArgsType(env, eventValueType == napi_string, "type", "Wrong type of arguments, required string")) {
            return nullptr;
        }

        napi_valuetype eventHandleType = napi_undefined;
        napi_typeof(env, argv[1], &eventHandleType);
        if (!CheckArgsType(env, eventHandleType == napi_function, "callback",
                           "Wrong type of arguments, required  function")) {
            return nullptr;
        }
        size_t typeLen = 0;
        napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);

        if (!CheckArgsVal(env, typeLen > 0, "type", "typeLen == 0")) {
            return nullptr;
        }
        if (!CheckArgsVal(env, typeLen < NAPI_BUF_LENGTH, "type", "typeLen >= MAXLEN")) {
            return nullptr;
        }
        char type[NAPI_BUF_LENGTH] = {0};
        napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);

        std::string eventType = type;
        LOGI("JsOn for eventType %s ", eventType.c_str());

        napi_ref handlerRef = nullptr;
        napi_create_reference(env, argv[1], 1, &handlerRef);
        if (handlerRef == nullptr) {
            LOGE("JsOn create reference fail");
            return nullptr;
        }
        std::lock_guard<std::mutex> autoLock(g_eventMapLock);
        g_eventMap[eventType] = handlerRef;
        return result;
    }

    napi_value JsOff(napi_env env, napi_callback_info info)
    {
        LOGI("JsOff in");
        GET_PARAMS(env, info, NAPI_ARGS_ONE);
        if(thisVar == nullptr){
            LOGE("thisVar is nullptr");
            return nullptr;
        }
        napi_value result = nullptr;
        if (!CheckArgsCount(env, argc == NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
            return nullptr;
        }

        napi_valuetype eventValueType = napi_undefined;
        napi_typeof(env, argv[0], &eventValueType);
        if (!CheckArgsType(env, eventValueType == napi_string, "type", "Wrong type of arguments, required string")) {
            return nullptr;
        }
        size_t typeLen = 0;
        napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);

        if (!CheckArgsVal(env, typeLen > 0, "type", "typeLen == 0")) {
            return nullptr;
        }
        if (!CheckArgsVal(env, typeLen < NAPI_BUF_LENGTH, "type", "typeLen >= MAXLEN")) {
            return nullptr;
        }
        char type[NAPI_BUF_LENGTH] = {0};
        napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);

        std::string eventType = type;
        LOGI("JsOff for eventType %s ", eventType.c_str());

        std::lock_guard<std::mutex> autoLock(g_eventMapLock);
        auto iter = g_eventMap.find(eventType);
        if (iter == g_eventMap.end()) {
            LOGE("eventType %s not find", eventType.c_str());
            return nullptr;
        }
        napi_delete_reference(env, iter->second);
        g_eventMap.erase(eventType);
        napi_get_undefined(env, &result);
        return result;
    }

}// namespace KhCommtraff
} // namespace OHOS
